﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
using Vit.Common.Collections;
using Vit.Common.Helpers;
using Vit.Web.Models;

namespace Vit.AdminModule.Areas.Admin.Providers
{
    public class SqlCategoryProvider : Vit.Web.Providers.ICategoryProvider
    {
        private WebProvidersDb db = new WebProvidersDb();

        #region ICategoryProvider Members

        public IQueryable<CategoryItem> GetAllCategories()
        {
            return db.Categories.OrderBy(o => o.Parent).ThenBy(o => o.Order);
        }

        public IQueryable<CategoryItem> GetCategoriesByGroup(string group)
        {
            return GetAllCategories().Where(o => o.Groups.Contains(group.ToLower()));
        }

        public IEnumerable<CategoryItem> BuildTree(IEnumerable<CategoryItem> items)
        {
            return HierarchyHelper.Build<CategoryItem, CategoryItem>(
                items.Where(o => o.Parent == null),
                o => o,
                o => o.Items,
                (p, c) => p.Items.Add(c));
        }

        public IQueryable<CategoryProperty> GetCategoryProperties(string category)
        {
            return db.CategoryProperties.Where(o => o.CategoryItemName == category).OrderBy(o => o.Order);
        }

        public IQueryable<CategoryPropertyValue> GetCategoryPropertyValues(string category, string objectType, string objectId)
        {
            return db.CategoryPropertyValues.Where(o => o.CategoryItemName == category && o.ObjectType == objectType && o.ObjectID == objectId).OrderBy(o => o.Property.Order);
        }

        public CategoryItem GetCategoryByName(string name)
        {
            return db.Categories.FirstOrDefault(o => o.Name == name);
        }

        public bool AddCategory(CategoryItem category)
        {
            db.Categories.Add(category);
            db.SaveChanges();
            return true;
        }

        public bool UpdateCategory(CategoryItem category)
        {
            db.Entry<CategoryItem>(category).State = System.Data.EntityState.Modified;
            db.SaveChanges();
            return true;
        }

        public bool RemoveCategoryWithItems(CategoryItem category)
        {
            db.Categories.Remove(category);
            db.SaveChanges();
            return true;
        }

        public bool AddCategoryProperty(CategoryProperty cateProperty)
        {
            db.CategoryProperties.Add(cateProperty);
            db.SaveChanges();
            return true;
        }

        public bool UpdateCategoryProperty(CategoryProperty cateProperty)
        {
            db.Entry<CategoryProperty>(cateProperty).State = System.Data.EntityState.Modified;
            db.SaveChanges();
            return true;
        }

        public bool RemoveCategoryProperty(CategoryProperty cateProperty)
        {
            db.CategoryProperties.Remove(cateProperty);
            db.SaveChanges();
            return true;
        }

        public bool SetCategoryPropertyValue(string category, string objType, string objId, string propName, string value)
        {
            CategoryPropertyValue cpVal = db.CategoryPropertyValues.FirstOrDefault(o => o.CategoryItemName == category && o.PropertyName == propName && o.ObjectType == objType && o.ObjectID == objId);
            if (cpVal == null)
            {
                cpVal = new CategoryPropertyValue()
                {
                    CategoryItemName = category,
                    PropertyName = propName,
                    ObjectType = objType,
                    ObjectID = objId,
                    Value = value
                };
                db.CategoryPropertyValues.Add(cpVal);
                db.SaveChanges();
            }
            else
            {
                cpVal.Value = value;
                db.SaveChanges();
            }
            return true;
        }

        #endregion

        #region IProvider Members

        public string Name
        {
            get { return "SqlCategoryProvider"; }
        }

        #endregion
    }
}